package cn.wizzer.app.sys.commons.core;

import cn.wizzer.app.sys.commons.base.Globals;
import cn.wizzer.app.sys.modules.models.*;
import cn.wizzer.app.sys.modules.services.SysParamService;
import org.nutz.boot.NbApp;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.impl.FileSqlManager;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Mirror;
import org.nutz.lang.Times;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.Modules;

import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Enumeration;
import java.util.List;

/**
 * Created by wizzer on 2018/3/16.
 */
@IocBean(create = "init", depose = "depose")
@Modules(packages = "cn.wizzer")
public class DubboRpcSysMainLauncher {
    private static final Log log = Logs.get();

    @Inject
    private Dao dao;

    @Inject
    private RedisService redisService;
    @Inject
    private SysParamService sysParamService;

    public static void main(String[] args) throws Exception {
        NbApp nb = new NbApp().setArgs(args).setPrintProcDoc(true);
        nb.getAppContext().setMainPackage("cn.wizzer");
        nb.run();
    }

    public void init() {
        //清空缓存
//        redisService.flushDB();

        //通过POJO类创建表结构
        try {
            Daos.createTablesInPackage(dao, "cn.wizzer.app.sys", false);
            //通过POJO类修改表结构
            //Daos.migration(dao, "cn.wizzer.app.sys", true, false);


            // 初始化加载数据库中的敏感词
            List<SysSensitive> sensitiveList = dao.query(SysSensitive.class, Cnd.NEW());
            for (SysSensitive sensitive : sensitiveList) {
                Globals.SENSITIVE_FILTER.put(sensitive.getWords());
            }
            // 若必要的数据表不存在，则初始化数据库
            if (0 == dao.count(SysUser.class)) {
                //执行SQL脚本
                FileSqlManager fm = new FileSqlManager("db/");
                List<Sql> sqlList = fm.createCombo(fm.keys());
                Sql[] sqls = sqlList.toArray(new Sql[sqlList.size()]);
                for (Sql sql : sqls) {
                    try{
                        dao.execute(sql);
                    }catch (Exception e){
                        log.error(e);
                    }

                }
                //初始化配置表
                SysConfig conf = new SysConfig();
                conf.setConfigKey("AppName");
                conf.setConfigValue("Hello-NB");
                conf.setNote("系统名称");
                dao.insert(conf);
                conf = new SysConfig();
                conf.setConfigKey("AppShrotName");
                conf.setConfigValue("HelloWk");
                conf.setNote("系统短名称");
                dao.insert(conf);
                conf = new SysConfig();
                conf.setConfigKey("AppDomain");
                conf.setConfigValue("http://127.0.0.1:8080");
                conf.setNote("系统域名");
                dao.insert(conf);
                conf = new SysConfig();
                conf.setConfigKey("AppFileDomain");
                conf.setConfigValue("");
                conf.setNote("文件访问域名");
                dao.insert(conf);
                conf = new SysConfig();
                conf.setConfigKey("AppUploadBase");
                conf.setConfigValue("/upload");
                conf.setNote("文件访问路径");
                dao.insert(conf);
                conf = new SysConfig();
                conf.setConfigKey("SysUserSessionOnlyOne");
                conf.setConfigValue("false");
                conf.setNote("用户登录只允许一个Session实例(为true时退出登录会更新sys_user表在线状态)");
                dao.insert(conf);
                conf = new SysConfig();
                conf.setConfigKey("WebNotification");
                conf.setConfigValue("false");
                conf.setNote("启用浏览器通知");
                dao.insert(conf);
                //初始化单位
                SysUnit unit = new SysUnit();
                unit.setPath("0001");
                unit.setName("系统管理");
                unit.setAliasName("System");
                unit.setLocation(0);
                unit.setAddress("银河-太阳系-地球");
                unit.setEmail("");
                unit.setTelephone("");
                unit.setHasChildren(false);
                unit.setParentId("");
                unit.setWebsite("");
                SysUnit dbunit = dao.insert(unit);


                //初始化角色
                SysRole role = new SysRole();
                role.setName("公共角色");
                role.setCode("public");
                role.setAliasName("Public");
                role.setNote("All user has role");
                role.setUnitid("");
                role.setDisabled(false);
                dao.insert(role);
                role = new SysRole();
                role.setName("系统管理员");
                role.setCode("sysadmin");
                role.setAliasName("Sysadmin");
                role.setNote("System Admin");
                role.setUnitid("");
                role.setMenus(dao.query(SysMenu.class,null));
                role.setDisabled(false);
                SysRole dbrole = dao.insert(role);
                //初始化用户
                SysUser user = new SysUser();
                user.setLoginname("superadmin");
                user.setUsername("超级管理员");
                user.setOpAt(Times.getTS());
                //String slat=R.UU32();
                //new Sha256Hash("1",ByteSource.Util.bytes(s), 1024).toHex();
                user.setSalt("r5tdr01s7uglfokpsdmtu15602");
                user.setPassword("1bba9287ebc50b766bff84273d11ccefaa7a8da95d078960f05f116e9d970fb0");
                user.setLoginIp("127.0.0.1");
                user.setLoginAt(0L);
                user.setLoginCount(0);
                user.setEmail("");
                user.setLoginTheme("palette.3.css");
                user.setLoginBoxed(false);
                user.setLoginScroll(true);
                user.setLoginSidebar(false);
                user.setLoginPjax(true);
                user.setUnitid(dbunit.getId());
                SysUser dbuser = dao.insert(user);
                //不同的插入数据方式(安全)
                dao.insert("sys_user_unit", Chain.make("userId", dbuser.getId()).add("unitId", dbunit.getId()));
                dao.insert("sys_user_role", Chain.make("userId", dbuser.getId()).add("roleId", dbrole.getId()));

                //菜单关联到角色
                dao.execute(Sqls.create("INSERT INTO sys_role_menu(roleId,menuId) SELECT @roleId,id FROM sys_menu").setParam("roleId", dbrole.getId()));
                //消息中心放第一个位置
                dao.execute(Sqls.create("update sys_menu set location=0 where path='00010003'"));
                //初始化自定义路由
                SysRoute route = new SysRoute();
                route.setDisabled(false);
                route.setUrl("/sysadmin");
                route.setToUrl("/platform/login");
                route.setType("hide");
                dao.insert(route);
                //初始化全局参数
                sysParamService.fetch();
            }
        } catch (Exception e) {
        }


    }

    public void depose() {
        // 非mysql数据库,或多webapp共享mysql驱动的话,以下语句删掉
        try {
            Mirror.me(Class.forName("com.mysql.jdbc.AbandonedConnectionCleanupThread")).invoke(null, "shutdown");
        } catch (Throwable e) {
        }
        // 解决com.alibaba.druid.proxy.DruidDriver和com.mysql.jdbc.Driver在reload时报warning的问题
        // 多webapp共享mysql驱动的话,以下语句删掉
        Enumeration<Driver> en = DriverManager.getDrivers();
        while (en.hasMoreElements()) {
            try {
                Driver driver = en.nextElement();
                String className = driver.getClass().getName();
                log.debug("deregisterDriver: " + className);
                DriverManager.deregisterDriver(driver);
            } catch (Exception e) {
            }
        }
    }
}
